home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / utils / fmgr / fmgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  29.8 KB  |  1,017 lines

  1. /*
  2.  * fmgr.c --
  3.  *    the C function manager interface.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <varargs.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10.  
  11. #include "tmp/c.h"
  12. #include "tmp/postgres.h"
  13.  
  14. #include "utils/fmgr.h"
  15. #include "utils/builtins.h"
  16.  
  17. #include "nodes/pg_lisp.h"
  18. #include "catalog/pg_proc.h"
  19. #include "catalog/pg_language.h"
  20. #include "catalog/syscache.h"
  21. #include "rules/params.h"
  22. #include "utils/oidcompos.h"
  23.  
  24. #include "utils/log.h"
  25. RcsId("$Header: /private/postgres/src/utils/fmgr/RCS/fmgr.c,v 1.94 1992/08/16 03:48:52 mer Exp $");
  26.  
  27. /*
  28.  *    procedure OID -> function mapping
  29.  *
  30.  *    XXX Keep this thing sorted by procedure OID!
  31.  *        It gets binary-searched ...
  32.  */
  33.  
  34. typedef struct {
  35.     ObjectId    proid;
  36.     int16        nargs;
  37.     func_ptr    func;
  38. } FmgrCall;
  39.  
  40. static FmgrCall    builtins[] = {
  41.     { F_BOOLIN,        1, (func_ptr) boolin },
  42.     { F_BOOLOUT,        1, (func_ptr) boolout },
  43.     { F_BYTEAIN,        1, (func_ptr) byteain },
  44.     { F_BYTEAOUT,        1, (func_ptr) byteaout },
  45.     { F_CHARIN,        1, (func_ptr) charin },
  46.     { F_CHAROUT,        1, (func_ptr) charout },
  47.     { F_CHAR16IN,        1, (func_ptr) char16in },
  48.     { F_CHAR16OUT,        1, (func_ptr) char16out },
  49.     { F_DATETIMEIN,        1, (func_ptr) dtin },
  50.     { F_DATETIMEOUT,    1, (func_ptr) dtout },
  51.     { F_INT2IN,        1, (func_ptr) int2in },
  52.     { F_INT2OUT,        1, (func_ptr) int2out },
  53.     { F_INT28IN,        1, (func_ptr) int28in },
  54.     { F_INT28OUT,        1, (func_ptr) int28out },
  55.     { F_INT4IN,        1, (func_ptr) int4in },
  56.     /* F_OIDIN == F_INT4IN */
  57.     { F_INT4OUT,        1, (func_ptr) int4out },
  58.     /* F_OIDOUT == F_INT4OUT */
  59.     { F_REGPROCIN,        1, (func_ptr) regprocin },
  60.     { F_REGPROCOUT,        1, (func_ptr) regprocout },
  61.     { F_TEXTIN,        1, (func_ptr) textin },
  62.     { F_TEXTOUT,        1, (func_ptr) textout },
  63.     { F_TIDIN,        1, (func_ptr) tidin },
  64.     { F_TIDOUT,        1, (func_ptr) tidout },
  65.     { F_XIDIN,        1, (func_ptr) StringFormTransactionId },
  66.     { F_XIDOUT,        1, (func_ptr) TransactionIdFormString },
  67.     { F_CIDIN,        1, (func_ptr) cidin },
  68.     { F_CIDOUT,        1, (func_ptr) cidout },
  69.     { F_OID8IN,        1, (func_ptr) oid8in },
  70.     { F_OID8OUT,        1, (func_ptr) oid8out },
  71.     { F_LOCKIN,        1, (func_ptr) StringToRuleLock },
  72.     { F_LOCKOUT,        1, (func_ptr) RuleLockToString },
  73.     { F_STUBIN,        1, (func_ptr) stubin },
  74.     { F_STUBOUT,        1, (func_ptr) stubout },
  75.  
  76.      { F_BOOLEQ,        2, (func_ptr) chareq },
  77.     { F_CHAREQ,        2, (func_ptr) chareq },
  78.     { F_CHAR16EQ,        2, (func_ptr) char16eq },
  79.     { F_INT2EQ,        2, (func_ptr) int2eq },
  80.     { F_INT2LT,        2, (func_ptr) int2lt },
  81.     { F_INT4EQ,        2, (func_ptr) int4eq },
  82.     { F_INT4LT,        2, (func_ptr) int4lt },
  83.     { F_TEXTEQ,        2, (func_ptr) texteq },
  84.     { F_XIDEQ,        2, (func_ptr) TransactionIdEquals },
  85.     { F_CIDEQ,        2, (func_ptr) int4eq },
  86.     { F_CHARNE,        2, (func_ptr) charne },
  87.     { F_CHARLT,        2, (func_ptr) charlt },
  88.     { F_CHARLE,        2, (func_ptr) charle },
  89.     { F_CHARGT,        2, (func_ptr) chargt },
  90.     { F_CHARGE,        2, (func_ptr) charge },
  91.     { F_CHARPL,        2, (func_ptr) charpl },
  92.     { F_CHARMI,        2, (func_ptr) charmi },
  93.     { F_CHARMUL,        2, (func_ptr) charmul },
  94.     { F_CHARDIV,        2, (func_ptr) chardiv },
  95.     { F_CHAR16REGEXEQ,    2, (func_ptr) char16regexeq },
  96.     { F_CHAR16REGEXNE,    2, (func_ptr) char16regexne },
  97.     { F_TEXTREGEXEQ,    2, (func_ptr) textregexeq },
  98.     { F_TEXTREGEXNE,    2, (func_ptr) textregexne },
  99.  
  100.     { F_BOOLNE,        2, (func_ptr) charne },
  101.  
  102.     { F_RTSEL,         7, (func_ptr) rtsel },
  103.     { F_RTNPAGE,         7, (func_ptr) rtnpage },
  104.     /*
  105.      * btree selectivity functions
  106.      */
  107.     { F_BTREESEL,         7, (func_ptr) btreesel },
  108.     { F_BTREENPG,         7, (func_ptr) btreenpage },
  109.  
  110.     { F_EQSEL,         5, (func_ptr) eqsel },
  111.     { F_NEQSEL,         5, (func_ptr) neqsel },
  112.     { F_INTLTSEL,         5, (func_ptr) intltsel },
  113.     { F_INTGTSEL,         5, (func_ptr) intgtsel },
  114.     { F_EQJOINSEL,         5, (func_ptr) eqjoinsel },
  115.     { F_NEQJOINSEL,     5, (func_ptr) neqjoinsel },
  116.     { F_INTLTJOINSEL,     5, (func_ptr) intltjoinsel },
  117.     { F_INTGTJOINSEL,     5, (func_ptr) intgtjoinsel },
  118.  
  119.     { F_POINT_IN,        1, (func_ptr) point_in },
  120.     { F_POINT_OUT,        1, (func_ptr) point_out },
  121.     { F_LSEG_IN,        1, (func_ptr) lseg_in },
  122.     { F_LSEG_OUT,        1, (func_ptr) lseg_out },
  123.     { F_PATH_IN,        1, (func_ptr) path_in },
  124.     { F_PATH_OUT,        1, (func_ptr) path_out },
  125.     { F_BOX_IN,        1, (func_ptr) box_in },
  126.     { F_BOX_OUT,        1, (func_ptr) box_out },
  127.     { F_BOX_OVERLAP,    2, (func_ptr) box_overlap },
  128.     { F_BOX_GE,        2, (func_ptr) box_ge },
  129.     { F_BOX_GT,        2, (func_ptr) box_gt },
  130.     { F_BOX_EQ,        2, (func_ptr) box_eq },
  131.     { F_BOX_LT,        2, (func_ptr) box_lt },
  132.     { F_BOX_LE,        2, (func_ptr) box_le },
  133.     /*
  134.      *  F_BOX_SAME appears below -- no room here
  135.      */
  136.     { F_POINT_ABOVE,    2, (func_ptr) point_above },
  137.     { F_POINT_LEFT,        2, (func_ptr) point_left },
  138.     { F_POINT_RIGHT,    2, (func_ptr) point_right },
  139.     { F_POINT_BELOW,    2, (func_ptr) point_below },
  140.     { F_POINT_EQ,        2, (func_ptr) point_eq },
  141.     { F_ON_PB,        2, (func_ptr) on_pb },
  142.     { F_ON_PPATH,        2, (func_ptr) on_ppath },
  143.     { F_BOX_CENTER,        1, (func_ptr) box_center },
  144.     { F_AREASEL,         5, (func_ptr) areasel },
  145.     { F_AREAJOINSEL,     5, (func_ptr) areajoinsel },
  146.     { F_INT4MUL,        2, (func_ptr) int4mul },
  147.     { F_INT4FAC,        1, (func_ptr) int4fac },
  148.     { F_POINTDIST,        2, (func_ptr) pointdist },
  149.     { F_INT4NE,        2, (func_ptr) int4ne },
  150.     { F_INT2NE,        2, (func_ptr) int2ne },
  151.     { F_INT2GT,        2, (func_ptr) int2gt },
  152.     { F_INT4GT,        2, (func_ptr) int4gt },
  153.     { F_INT2LE,        2, (func_ptr) int2le },
  154.     { F_INT4LE,        2, (func_ptr) int4le },
  155.     { F_INT4GE,        2, (func_ptr) int4ge },
  156.     { F_INT2GE,        2, (func_ptr) int2ge },
  157.     { F_INT2MUL,        2, (func_ptr) int2mul },
  158.     { F_INT2DIV,        2, (func_ptr) int2div },
  159.     { F_INT4DIV,        2, (func_ptr) int4div },
  160.     { F_INT2MOD,        2, (func_ptr) int2mod },
  161.     { F_INT4MOD,        2, (func_ptr) int4mod },
  162.     { F_TEXTNE,        2, (func_ptr) textne },
  163.     { F_INT24EQ,        2, (func_ptr) int4eq },
  164.     { F_INT42EQ,        2, (func_ptr) int4eq },
  165.     { F_INT24LT,        2, (func_ptr) int4lt },
  166.     { F_INT42LT,        2, (func_ptr) int4lt },
  167.     { F_INT24GT,        2, (func_ptr) int4gt },
  168.     { F_INT42GT,        2, (func_ptr) int4gt },
  169.     { F_INT24NE,        2, (func_ptr) int4ne },
  170.     { F_INT42NE,        2, (func_ptr) int4ne },
  171.     { F_INT24LE,        2, (func_ptr) int4le },
  172.     { F_INT42LE,        2, (func_ptr) int4le },
  173.     { F_INT24GE,        2, (func_ptr) int4ge },
  174.     { F_INT42GE,        2, (func_ptr) int4ge },
  175.     { F_INT24MUL,        2, (func_ptr) int4mul },
  176.     { F_INT42MUL,        2, (func_ptr) int4mul },
  177.     { F_INT24DIV,        2, (func_ptr) int4div },
  178.     { F_INT42DIV,        2, (func_ptr) int4div },
  179.     { F_INT24MOD,        2, (func_ptr) int4mod },
  180.     { F_INT42MOD,        2, (func_ptr) int4mod },
  181.     { F_INT2PL,        2, (func_ptr) int2pl },
  182.     { F_INT4PL,        2, (func_ptr) int4pl },
  183.     { F_INT24PL,        2, (func_ptr) int4pl },
  184.     { F_INT42PL,        2, (func_ptr) int4pl },
  185.     { F_INT2MI,        2, (func_ptr) int2mi },
  186.     { F_INT4MI,        2, (func_ptr) int4mi },
  187.     { F_INT24MI,        2, (func_ptr) int4mi },
  188.     { F_INT42MI,        2, (func_ptr) int4mi },
  189.     { F_OIDEQ,        2, (func_ptr) int4eq },
  190.     { F_OIDNE,        2, (func_ptr) int4ne },
  191.     { F_BOX_SAME,        2, (func_ptr) box_same },
  192.     { F_BOX_CONTAIN,    2, (func_ptr) box_contain },
  193.     { F_BOX_LEFT,        2, (func_ptr) box_left },
  194.     { F_BOX_OVERLEFT,    2, (func_ptr) box_overleft },
  195.     { F_BOX_OVERRIGHT,    2, (func_ptr) box_overright },
  196.     { F_BOX_RIGHT,        2, (func_ptr) box_right },
  197.     { F_BOX_CONTAINED,    2, (func_ptr) box_contained },
  198.     { F_RT_BOX_UNION,    2, (func_ptr) rt_box_union },
  199.     { F_RT_BOX_INTER,    2, (func_ptr) rt_box_inter },
  200.     { F_RT_BOX_SIZE,    1, (func_ptr) rt_box_size },
  201.     { F_RT_BIGBOX_SIZE,    1, (func_ptr) rt_bigbox_size },
  202.     { F_RT_POLY_UNION,    2, (func_ptr) rt_poly_union },
  203.     { F_RT_POLY_INTER,    2, (func_ptr) rt_poly_inter },
  204.     { F_RT_POLY_SIZE,    1, (func_ptr) rt_poly_size },
  205.     { F_FLOAT4IN,        1, (func_ptr) float4in },
  206.     { F_FLOAT4OUT,        1, (func_ptr) float4out },
  207.     { F_FLOAT4MUL,        2, (func_ptr) float4mul },
  208.     { F_FLOAT4DIV,        2, (func_ptr) float4div },
  209.     { F_FLOAT4PL,        2, (func_ptr) float4pl },
  210.     { F_FLOAT4MI,        2, (func_ptr) float4mi },
  211.     { F_FLOAT4UM,        1, (func_ptr) float4um },
  212.     { F_FLOAT4ABS,        1, (func_ptr) float4abs },
  213.     { F_FLOAT4INC,        1, (func_ptr) float4inc },
  214.     { F_FLOAT4LARGER,    2, (func_ptr) float4larger },
  215.     { F_FLOAT4SMALLER,    2, (func_ptr) float4smaller },
  216.     { F_INT4UM,        1, (func_ptr) int4um },
  217.     { F_INT2UM,        1, (func_ptr) int2um },
  218.     { F_FLOAT8IN,        1, (func_ptr) float8in },
  219.     { F_FLOAT8OUT,        1, (func_ptr) float8out },
  220.     { F_FLOAT8MUL,        2, (func_ptr) float8mul },
  221.     { F_FLOAT8DIV,        2, (func_ptr) float8div },
  222.     { F_FLOAT8PL,        2, (func_ptr) float8pl },
  223.     { F_FLOAT8MI,        2, (func_ptr) float8mi },
  224.     { F_FLOAT8UM,        1, (func_ptr) float8um },
  225.     { F_FLOAT8ABS,        1, (func_ptr) float8abs },
  226.     { F_FLOAT8INC,        1, (func_ptr) float8inc },
  227.     { F_FLOAT8LARGER,    2, (func_ptr) float8larger },
  228.     { F_FLOAT8SMALLER,    2, (func_ptr) float8smaller },
  229.     { F_DROUND,        1, (func_ptr) dround },
  230.     { F_DTRUNC,        1, (func_ptr) dtrunc },
  231.     { F_DSQRT,        1, (func_ptr) dsqrt },
  232.     { F_DCBRT,        1, (func_ptr) dcbrt },
  233.     { F_DPOW,        2, (func_ptr) dpow },
  234.     { F_DEXP,        1, (func_ptr) dexp },
  235.     { F_DLOG,        1, (func_ptr) dlog1 },
  236.     { F_ABSTIMEIN,        1, (func_ptr) nabstimein },
  237.     { F_ABSTIMEOUT,        1, (func_ptr) nabstimeout },
  238.     { F_RELTIMEIN,        1, (func_ptr) reltimein },
  239.     { F_RELTIMEOUT,        1, (func_ptr) reltimeout },
  240.     { F_TIMEPL,        1, (func_ptr) timepl },
  241.      
  242.     { F_TIMEMI,        2, (func_ptr) timemi },
  243.     { F_TINTERVALIN,    1, (func_ptr) tintervalin },
  244.     { F_TINTERVALOUT,    1, (func_ptr) tintervalout },
  245.     { F_ININTERVAL,        2, (func_ptr) ininterval },
  246.     { F_INTERVALREL,    1, (func_ptr) intervalrel },
  247.     { F_TIMENOW,        0, (func_ptr) timenow },
  248.  
  249.     { F_ABSTIMEEQ,        2, (func_ptr) abstimeeq },
  250.     { F_ABSTIMENE,        2, (func_ptr) abstimene },
  251.     { F_ABSTIMELT,        2, (func_ptr) abstimelt },
  252.     { F_ABSTIMEGT,        2, (func_ptr) abstimegt },
  253.     { F_ABSTIMELE,        2, (func_ptr) abstimele },
  254.     { F_ABSTIMEGE,        2, (func_ptr) abstimege },
  255.     { F_RELTIMEEQ,          2, (func_ptr) reltimeeq },
  256.     { F_RELTIMENE,          2, (func_ptr) reltimene },
  257.     { F_RELTIMELT,          2, (func_ptr) reltimelt },
  258.     { F_RELTIMEGT,          2, (func_ptr) reltimegt },
  259.     { F_RELTIMELE,          2, (func_ptr) reltimele },
  260.     { F_RELTIMEGE,          2, (func_ptr) reltimege },
  261.  
  262.     { F_INTERVALEQ,         2, (func_ptr) intervaleq },
  263.     { F_INTERVALCT,         2, (func_ptr) intervalct },
  264.     { F_INTERVALOV,         2, (func_ptr) intervalov },
  265.     { F_INTERVALLENEQ,      2, (func_ptr) intervalleneq },
  266.     { F_INTERVALLENNE,      2, (func_ptr) intervallenne },
  267.     { F_INTERVALLENLT,      2, (func_ptr) intervallenlt },
  268.     { F_INTERVALLENGT,      2, (func_ptr) intervallengt },
  269.     { F_INTERVALLENLE,      2, (func_ptr) intervallenle },
  270.     { F_INTERVALLENGE,      2, (func_ptr) intervallenge },
  271.     { F_INTERVALSTART,      1, (func_ptr) intervalstart },
  272.     { F_INTERVALEND,        1, (func_ptr) intervalend },
  273.  
  274.     { F_INT2FAC,        1, (func_ptr) int2fac },
  275.     { F_FLOAT48MUL,        2, (func_ptr) float48mul },
  276.     { F_FLOAT48DIV,        2, (func_ptr) float48div },
  277.     { F_FLOAT48PL,        2, (func_ptr) float48pl },
  278.     { F_FLOAT48MI,        2, (func_ptr) float48mi },
  279.     { F_FLOAT84MUL,        2, (func_ptr) float84mul },
  280.     { F_FLOAT84DIV,        2, (func_ptr) float84div },
  281.     { F_FLOAT84PL,        2, (func_ptr) float84pl },
  282.     { F_FLOAT84MI,        2, (func_ptr) float84mi },
  283.     { F_FLOAT4EQ,        2, (func_ptr) float4eq },
  284.     { F_FLOAT4NE,        2, (func_ptr) float4ne },
  285.     { F_FLOAT4LT,        2, (func_ptr) float4lt },
  286.     { F_FLOAT4LE,        2, (func_ptr) float4le },
  287.     { F_FLOAT4GT,        2, (func_ptr) float4gt },
  288.     { F_FLOAT4GE,        2, (func_ptr) float4ge },
  289.     { F_FLOAT8EQ,        2, (func_ptr) float8eq },
  290.     { F_FLOAT8NE,        2, (func_ptr) float8ne },
  291.     { F_FLOAT8LT,        2, (func_ptr) float8lt },
  292.     { F_FLOAT8LE,        2, (func_ptr) float8le },
  293.     { F_FLOAT8GT,        2, (func_ptr) float8gt },
  294.     { F_FLOAT8GE,        2, (func_ptr) float8ge },
  295.     { F_FLOAT48EQ,        2, (func_ptr) float48eq },
  296.     { F_FLOAT48NE,        2, (func_ptr) float48ne },
  297.     { F_FLOAT48LT,        2, (func_ptr) float48lt },
  298.     { F_FLOAT48LE,        2, (func_ptr) float48le },
  299.     { F_FLOAT48GT,        2, (func_ptr) float48gt },
  300.     { F_FLOAT48GE,        2, (func_ptr) float48ge },
  301.     { F_FLOAT84EQ,        2, (func_ptr) float84eq },
  302.     { F_FLOAT84NE,        2, (func_ptr) float84ne },
  303.     { F_FLOAT84LT,        2, (func_ptr) float84lt },
  304.     { F_FLOAT84LE,        2, (func_ptr) float84le },
  305.     { F_FLOAT84GT,        2, (func_ptr) float84gt },
  306.     { F_FLOAT84GE,        2, (func_ptr) float84ge },
  307.     { F_F4TOF8,        2, (func_ptr) ftod },
  308.     { F_F8TOF4,        2, (func_ptr) dtof },
  309.     { F_I2TOI4,        2, (func_ptr) itoi },
  310.     { F_I4TOI2,        2, (func_ptr) itoi },
  311.     { F_KEYFIRSTEQ,        2, (func_ptr) keyfirsteq },
  312.  
  313.     /* no room for this above */
  314.     { F_RTINSERT,        3, (func_ptr) rtinsert },
  315.     { F_RTDELETE,        2, (func_ptr) rtdelete },
  316.     { F_RTGETTUPLE,     2, (func_ptr) rtgettuple },
  317.     { F_RTBUILD,         9, (func_ptr) rtbuild },
  318.     { F_RTBEGINSCAN,     4, (func_ptr) rtbeginscan },
  319.     { F_RTENDSCAN,        1, (func_ptr) rtendscan },
  320.     { F_RTMARKPOS,        1, (func_ptr) rtmarkpos },
  321.     { F_RTRESTRPOS,        1, (func_ptr) rtrestrpos },
  322.     { F_RTRESCAN,        3, (func_ptr) rtrescan },
  323.  
  324.     /* new btrees */
  325.     { F_NBTGETTUPLE,    2, (func_ptr) btgettuple },
  326.     { F_NBTINSERT,        3, (func_ptr) btinsert },
  327.     { F_NBTDELETE,        2, (func_ptr) btdelete },
  328.     { F_NBTBEGINSCAN,    4, (func_ptr) btbeginscan },
  329.     { F_NBTRESCAN,        3, (func_ptr) btrescan },
  330.     { F_NBTENDSCAN,        1, (func_ptr) btendscan },
  331.     { F_NBTMARKPOS,        1, (func_ptr) btmarkpos },
  332.     { F_NBTRESTRPOS,    1, (func_ptr) btrestrpos },
  333.     { F_NBTBUILD,        9, (func_ptr) btbuild },
  334.     { F_POLY_SAME,        2, (func_ptr) poly_same },
  335.     { F_POLY_CONTAIN,    2, (func_ptr) poly_contain },
  336.     { F_POLY_LEFT,        2, (func_ptr) poly_left },
  337.     { F_POLY_OVERLEFT,    2, (func_ptr) poly_overleft },
  338.     { F_POLY_OVERRIGHT,    2, (func_ptr) poly_overright },
  339.     { F_POLY_RIGHT,        2, (func_ptr) poly_right },
  340.     { F_POLY_CONTAINED,    2, (func_ptr) poly_contained },
  341.     { F_POLY_OVERLAP,    2, (func_ptr) poly_overlap },
  342.     { F_POLY_IN,        1, (func_ptr) poly_in },
  343.     { F_POLY_OUT,        1, (func_ptr) poly_out },
  344.     /* per-opclass comparison functions for new btrees */
  345.     { F_BTINT2CMP,        2, (func_ptr) btint2cmp },
  346.     { F_BTINT4CMP,        2, (func_ptr) btint4cmp },
  347.     { F_BTINT42CMP,        2, (func_ptr) btint42cmp },
  348.     { F_BTINT24CMP,        2, (func_ptr) btint24cmp },
  349.     { F_BTFLOAT4CMP,    2, (func_ptr) btfloat4cmp },
  350.     { F_BTFLOAT8CMP,    2, (func_ptr) btfloat8cmp },
  351.     { F_BTOIDCMP,        2, (func_ptr) btoidcmp },
  352.     { F_BTABSTIMECMP,    2, (func_ptr) btabstimecmp },
  353.     { F_BTCHARCMP,        2, (func_ptr) btcharcmp },
  354.     { F_BTCHAR16CMP,    2, (func_ptr) btchar16cmp },
  355.     { F_BTTEXTCMP,        2, (func_ptr) bttextcmp },
  356.  
  357.     { F_LSEG_DISTANCE,    2, (func_ptr) lseg_distance },
  358.     { F_LSEG_INTERPT,    2, (func_ptr) lseg_interpt },
  359.     { F_DIST_PS,        2, (func_ptr) dist_ps },
  360.     { F_DIST_PB,        2, (func_ptr) dist_pb },
  361.     { F_DIST_SB,        2, (func_ptr) dist_sb },
  362.     { F_CLOSE_PS,        2, (func_ptr) close_ps },
  363.     { F_CLOSE_PB,        2, (func_ptr) close_pb },
  364.     { F_CLOSE_SB,        2, (func_ptr) close_sb },
  365.     { F_ON_PS,        2, (func_ptr) on_ps },
  366.     { F_PATH_DISTANCE,    2, (func_ptr) path_distance },
  367.     { F_DIST_PPTH,        2, (func_ptr) dist_ppth },
  368.     { F_ON_SB,        2, (func_ptr) on_sb },
  369.     { F_INTER_SB,        2, (func_ptr) inter_sb },
  370.  
  371.     { F_GETATTRIBUTEBYNAME,    3, (func_ptr) GetAttributeByName },
  372.     { F_INT4NOTIN,         2, (func_ptr) int4notin },
  373.     { F_OIDNOTIN,         2, (func_ptr) oidnotin },
  374.     { F_INT44IN,        1, (func_ptr) int44in },
  375.     { F_INT44OUT,        1, (func_ptr) int44out },
  376.     { F_GETATTRIBUTEBYNUM,    3, (func_ptr) GetAttributeByNum },
  377.  
  378.     { F_CHAR16LT,        2, (func_ptr) char16lt },
  379.     { F_CHAR16LE,        2, (func_ptr) char16le },
  380.     { F_CHAR16GT,        2, (func_ptr) char16gt },
  381.     { F_CHAR16GE,        2, (func_ptr) char16ge },
  382.     { F_CHAR16NE,        2, (func_ptr) char16ne },
  383.  
  384.     { F_LOCKADD,        2, (func_ptr) prs2LockUnion },
  385.     { F_LOCKRM,        2, (func_ptr) prs2RemoveAllLocksOfRule },
  386.     { F_PG_USERNAME,    0, (func_ptr) pg_username },
  387.     { F_USERFNTEST,        1, (func_ptr) userfntest },
  388.     { F_BYTEASIZE,        1, (func_ptr) byteaGetSize },
  389.     { F_BYTEAGETBYTE,    2, (func_ptr) byteaGetByte },
  390.     { F_BYTEASETBYTE,    3, (func_ptr) byteaSetByte },
  391.     { F_BYTEAGETBIT,    2, (func_ptr) byteaGetBit },
  392.     { F_BYTEASETBIT,    3, (func_ptr) byteaSetBit },
  393.     { F_PQTEST,        1, (func_ptr) pqtest },
  394.  
  395.     { F_TEXTLT,        2, (func_ptr) text_lt },
  396.     { F_TEXTLE,        2, (func_ptr) text_le },
  397.     { F_TEXTGT,        2, (func_ptr) text_gt },
  398.      { F_TEXTGE,        2, (func_ptr) text_ge },
  399.     { F_ARRAY_IN,    2, (func_ptr) array_in },
  400.     { F_ARRAY_OUT,    2, (func_ptr) array_out },
  401.     { F_FILENAME_IN,2, (func_ptr) filename_in },
  402.     { F_FILENAME_OUT,2, (func_ptr) filename_out },
  403.  
  404.     { F_SMGRIN, 1, (func_ptr) smgrin },
  405.     { F_SMGROUT, 1, (func_ptr) smgrout },
  406.     { F_SMGREQ, 2, (func_ptr) smgreq },
  407.     { F_SMGRNE, 2, (func_ptr) smgrne },
  408.  
  409.     { F_LO_FILEIN,  1, (func_ptr) lo_filein },
  410.     { F_LO_FILEOUT, 1, (func_ptr) lo_fileout},
  411.     { F_INT4INC,    1, (func_ptr) int4inc},
  412.     { F_INT2INC,    1, (func_ptr) int2inc},
  413.     { F_INT4LARGER, 2, (func_ptr) int4larger},
  414.     { F_INT4SMALLER,2, (func_ptr) int4smaller},
  415.     { F_INT2LARGER, 2, (func_ptr) int2larger},
  416.     { F_INT2SMALLER,2, (func_ptr) int2smaller},
  417.  
  418. #ifdef NOBTREE
  419.  
  420.     { F_NOBTGETTUPLE,    6, (func_ptr) nobtgettuple },
  421.     { F_NOBTINSERT,        3, (func_ptr) nobtinsert },
  422.     { F_NOBTDELETE,        2, (func_ptr) nobtdelete },
  423.     { F_NOBTBEGINSCAN,    4, (func_ptr) nobtbeginscan },
  424.     { F_NOBTRESCAN,        3, (func_ptr) nobtrescan },
  425.     { F_NOBTENDSCAN,    1, (func_ptr) nobtendscan },
  426.     { F_NOBTMARKPOS,    1, (func_ptr) nobtmarkpos },
  427.     { F_NOBTRESTRPOS,    1, (func_ptr) nobtrestrpos },
  428.     { F_NOBTBUILD,        9, (func_ptr) nobtbuild },
  429.  
  430. #endif /* NOBTREE */
  431.  
  432.     { F_FIMPORT,    1, (func_ptr) fimport },
  433.     { F_FEXPORT,    2, (func_ptr) fexport },
  434.     { F_FABSTRACT,    5, (func_ptr) fabstract },
  435.     { F_OIDINT4IN,    1, (func_ptr) oidint4in },
  436.     { F_OIDINT4OUT,    1, (func_ptr) oidint4out },
  437.     { F_OIDINT4LT,    2, (func_ptr) oidint4lt },
  438.     { F_OIDINT4LE,    2, (func_ptr) oidint4le },
  439.     { F_OIDINT4EQ,    2, (func_ptr) oidint4eq },
  440.     { F_OIDINT4GE,    2, (func_ptr) oidint4ge },
  441.     { F_OIDINT4GT,    2, (func_ptr) oidint4gt },
  442.     { F_OIDINT4NE,    2, (func_ptr) oidint4ne },
  443.     { F_OIDINT4CMP,    2, (func_ptr) oidint4cmp },
  444.     { F_MKOIDINT4,    2, (func_ptr) mkoidint4 },
  445.  
  446.     { F_OIDCHAR16IN,    1, (func_ptr) oidchar16in },
  447.     { F_OIDCHAR16OUT,    1, (func_ptr) oidchar16out },
  448.     { F_OIDCHAR16LT,    2, (func_ptr) oidchar16lt },
  449.     { F_OIDCHAR16LE,    2, (func_ptr) oidchar16le },
  450.     { F_OIDCHAR16EQ,    2, (func_ptr) oidchar16eq },
  451.     { F_OIDCHAR16GE,    2, (func_ptr) oidchar16ge },
  452.     { F_OIDCHAR16GT,    2, (func_ptr) oidchar16gt },
  453.     { F_OIDCHAR16NE,    2, (func_ptr) oidchar16ne },
  454.     { F_OIDCHAR16CMP,    2, (func_ptr) oidchar16cmp },
  455.     { F_MKOIDCHAR16,    2, (func_ptr) mkoidchar16 },
  456.  
  457.         { F_FILETOOID,          1, (func_ptr) FilenameToOID },
  458.         { F_LOCREATOID,         1, (func_ptr) LOcreatOID },
  459.         { F_LOOPEN,             2, (func_ptr) LOopen },
  460.         { F_LOCLOSE,            1, (func_ptr) LOclose },
  461.         { F_LOREAD,             2, (func_ptr) LOread },
  462.         { F_LOWRITE,            2, (func_ptr) LOwrite },
  463.         { F_LOLSEEK,            3, (func_ptr) LOlseek },
  464.         { F_LOCREAT,            3, (func_ptr) LOcreat },
  465.         { F_LOTELL,             1, (func_ptr) LOtell },
  466.         { F_LOFTRUNCATE,        2, (func_ptr) LOftruncate },
  467.         { F_LOSTAT,             1, (func_ptr) LOstat },
  468.         { F_LORENAME,           2, (func_ptr) LOrename },
  469.         { F_LOMKDIR,            2, (func_ptr) LOmkdir },
  470.         { F_LORMDIR,            1, (func_ptr) LOrmdir },
  471.         { F_LOUNLINK,           1, (func_ptr) LOunlink },
  472.  
  473.         { F_PFTPREAD,           3, (func_ptr) pftp_read },
  474.         { F_PFTPWRITE,          2, (func_ptr) pftp_write },
  475.         { F_REGTOOID,        1, (func_ptr) RegprocToOid },
  476.  
  477.     { F_PATH_INTER,        2, (func_ptr) path_inter },
  478.     { F_BOX_COPY,        1, (func_ptr) box_copy },
  479.     { F_BOX_AREA,        1, (func_ptr) box_area },
  480.     { F_BOX_LENGTH,        1, (func_ptr) box_length },
  481.     { F_BOX_HEIGHT,        1, (func_ptr) box_height },
  482.     { F_BOX_DISTANCE,    2, (func_ptr) box_distance },
  483.     { F_BOX_INTERSECT,    2, (func_ptr) box_intersect },
  484.     { F_BOX_DIAGONAL,    1, (func_ptr) box_diagonal },
  485.     { F_PATH_N_LT,        2, (func_ptr) path_n_lt },
  486.     { F_PATH_N_GT,        2, (func_ptr) path_n_gt },
  487.     { F_PATH_N_EQ,        2, (func_ptr) path_n_eq },
  488.     { F_PATH_N_LE,        2, (func_ptr) path_n_le },
  489.     { F_PATH_N_GE,        2, (func_ptr) path_n_ge },
  490.     { F_PATH_LENGTH,    1, (func_ptr) path_length },
  491.     { F_POINT_COPY,        1, (func_ptr) point_copy },
  492.     { F_POINT_VERT,        2, (func_ptr) point_vert },
  493.     { F_POINT_HORIZ,    2, (func_ptr) point_horiz },
  494.     { F_POINT_DISTANCE,    2, (func_ptr) point_distance },
  495.     { F_POINT_SLOPE,    2, (func_ptr) point_slope },
  496.     { F_LSEG_CONSTRUCT,    2, (func_ptr) lseg_construct },
  497.     { F_LSEG_INTERSECT,    2, (func_ptr) lseg_intersect },
  498.     { F_LSEG_PARALLEL,    2, (func_ptr) lseg_parallel },
  499.     { F_LSEG_PERP,        2, (func_ptr) lseg_perp },
  500.     { F_LSEG_VERTICAL,    1, (func_ptr) lseg_vertical },
  501.     { F_LSEG_HORIZONTAL,    1, (func_ptr) lseg_horizontal },
  502.     { F_LSEG_EQ,        2, (func_ptr) lseg_eq },
  503.     { F_NULLVALUE,             1, (func_ptr) NullValue },
  504.     { F_NONNULLVALUE,            1, (func_ptr) NonNullValue }
  505. };
  506.  
  507. static     n_builtins = lengthof(builtins);
  508.  
  509. char *c_lang_func_call_ptr(user_fn,n_arguments,values, isNull)
  510.     int         n_arguments;
  511.     FmgrValues    values;
  512.     func_ptr    user_fn;
  513.     Boolean *isNull;        
  514.  
  515. {
  516.     char        *returnValue = NULL;
  517.     switch(n_arguments)
  518.     {
  519.     case 0:
  520.         returnValue = (*user_fn)();
  521.         break;
  522.     case 1:
  523.         returnValue = (*user_fn)
  524.         (values.data[0], isNull);
  525.         break;
  526.     case 2:
  527.         returnValue = (*user_fn)
  528.         (values.data[0],
  529.          values.data[1]);
  530.         break;
  531.     case 3:
  532.         returnValue = (*user_fn)
  533.         (values.data[0],
  534.          values.data[1],
  535.          values.data[2]);
  536.         break;
  537.     case 4:
  538.         returnValue = (*user_fn)
  539.         (values.data[0],
  540.          values.data[1],
  541.          values.data[2],
  542.          values.data[3]);
  543.         break;
  544.     case 5:
  545.         returnValue = (*user_fn)
  546.         (values.data[0],
  547.          values.data[1],
  548.          values.data[2],
  549.          values.data[3],
  550.          values.data[4]);
  551.         break;
  552.     case 6:
  553.         returnValue = (*user_fn)
  554.         (values.data[0],
  555.          values.data[1],
  556.          values.data[2],
  557.          values.data[3],
  558.          values.data[4],
  559.          values.data[5]);
  560.         break;
  561.     case 7:
  562.         returnValue = (*user_fn)
  563.         (values.data[0],
  564.          values.data[1],
  565.          values.data[2],
  566.          values.data[3],
  567.          values.data[4],
  568.          values.data[5],
  569.          values.data[6]);
  570.         break;
  571.     case 8:
  572.         returnValue = (*user_fn)
  573.         (values.data[0],
  574.          values.data[1],
  575.          values.data[2],
  576.          values.data[3],
  577.          values.data[4],
  578.          values.data[5],
  579.          values.data[6],
  580.          values.data[7]);
  581.         break;
  582.     case 9:
  583.         returnValue = (*user_fn)
  584.         (values.data[0],
  585.          values.data[1],
  586.          values.data[2],
  587.          values.data[3],
  588.          values.data[4],
  589.          values.data[5],
  590.          values.data[6],
  591.          values.data[7],
  592.          values.data[8]);
  593.         break;
  594.     case 10:
  595.         returnValue = (*user_fn)
  596.         (values.data[0],
  597.          values.data[1],
  598.          values.data[2],
  599.          values.data[3],
  600.          values.data[4],
  601.          values.data[5],
  602.          values.data[6],
  603.          values.data[7],
  604.          values.data[8],
  605.          values.data[9]);
  606.         break;
  607.     default:
  608.         elog(WARN, "c_lang_call_ptr: too many args to function!");
  609.         break; /* Not really necessary, but why not? */
  610.     }
  611.     return(returnValue);
  612. }
  613.  
  614. /* The *isNull flag is set to true if one of the arguments to
  615.    the ADT functions is NULL, so it should not be initialised
  616.    to anything, the old value needs to be propagated or set
  617.    to true if necessary at the ADT functions */
  618.  
  619. char *c_lang_func_call_ptr_array(user_fn,nargs,args, isNull)
  620.      int         nargs;
  621.      char *args[];
  622.      func_ptr    user_fn;
  623.      Boolean *isNull;
  624.  
  625. {
  626.     char *returnValue;
  627.     switch (nargs)
  628.     {
  629.     case 0:
  630.         returnValue = (*user_fn)();
  631.         break;
  632.     case 1:
  633.         returnValue = (*user_fn)
  634.         (args[0], isNull);        /* This is because the ADT fn */
  635.         break;                /* NullValue() use isNull for */
  636.                         /* checking if args[0] is NULL*/
  637.     case 2:
  638.         returnValue = (*user_fn)
  639.         (args[0],
  640.          args[1]);
  641.         break;
  642.     case 3:
  643.         returnValue = (*user_fn)
  644.         (args[0],
  645.          args[1],
  646.          args[2]);
  647.         break;
  648.     case 4:
  649.         returnValue = (*user_fn)
  650.         (args[0],
  651.          args[1],
  652.          args[2],
  653.          args[3]);
  654.         break;
  655.     case 5:
  656.         returnValue = (*user_fn)
  657.         (args[0],
  658.          args[1],
  659.          args[2],
  660.          args[3],
  661.          args[4]);
  662.         break;
  663.     case 6:
  664.         returnValue = (*user_fn)
  665.         (args[0],
  666.          args[1],
  667.          args[2],
  668.          args[3],
  669.          args[4],
  670.          args[5]);
  671.         break;
  672.     case 7:
  673.         returnValue = (*user_fn)
  674.         (args[0],
  675.          args[1],
  676.          args[2],
  677.          args[3],
  678.          args[4],
  679.          args[5],
  680.          args[6]);
  681.         break;
  682.     case 8:
  683.         returnValue = (*user_fn)
  684.         (args[0],
  685.          args[1],
  686.          args[2],
  687.          args[3],
  688.          args[4],
  689.          args[5],
  690.          args[6],
  691.          args[7]);
  692.         break;
  693.     case 9:
  694.         returnValue = (*user_fn)
  695.         (args[0],
  696.          args[1],
  697.          args[2],
  698.          args[3],
  699.          args[4],
  700.          args[5],
  701.          args[6],
  702.          args[7],
  703.          args[8]);
  704.         break;
  705.     case 10:
  706.         returnValue = (*user_fn)
  707.         (args[0],
  708.          args[1],
  709.          args[2],
  710.          args[3],
  711.          args[4],
  712.          args[5],
  713.          args[6],
  714.          args[7],
  715.          args[8],
  716.          args[9]);
  717.         break;
  718.     default:
  719.         elog(WARN, "fmgr: too many args to function");
  720.         break; /* Not really necessary, but why not? */
  721.     }
  722.     return(returnValue);
  723. }
  724. char *postquel_lang_func_call_array(procedureId,pronargs,args)
  725.      ObjectId procedureId;
  726.      int    pronargs;
  727.      char *args[];    
  728. {
  729.     List query_descriptor = LispNil, qd = LispNil;
  730.     HeapTuple   procedureTuple;
  731.     ParamListInfo paramlist;
  732.     char *plan_str;
  733.     int status,x;
  734.     Datum *value;
  735.     Boolean *isnull;
  736.     
  737.  
  738.     plan_str = (char *)
  739.     SearchSysCacheGetAttribute(PROOID,Anum_pg_proc_prosrc, procedureId);
  740.     qd = StringToPlanWithParams(textout((struct varlena *)plan_str),¶mlist);
  741.     x=0; 
  742.     while(paramlist[x].kind != PARAM_INVALID) {
  743.     paramlist[x].value = (Datum) args[x];
  744.     x++;
  745.     }
  746.     if (prs2RunOnePlanAndGetValue(qd,paramlist, NULL, &value, &isnull))
  747.     return (char *) value;
  748.     else return (char *)NULL;
  749. }
  750. char *postquel_lang_func_call(procedureId,pronargs,values)
  751.      ObjectId procedureId;
  752.      int    pronargs;
  753.      FmgrValues    values;
  754. {
  755.  
  756.  
  757.     
  758. }
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765. ObjectId fmgr_func_lang(procedureId)
  766.      ObjectId procedureId;
  767. {
  768.     HeapTuple   procedureTuple;
  769.     ObjectId language;
  770.     int low, high,i;
  771.  
  772.     low = 0;
  773.     high = n_builtins;
  774.     while (low <= high) {
  775.     i = low + (high - low) / 2;
  776.     if (procedureId == builtins[i].proid)
  777.         break;
  778.     else if (procedureId > builtins[i].proid)
  779.         low = i + 1;
  780.     else
  781.         high = i - 1;
  782.     }
  783.  
  784.     /*
  785.      * If we found the procedure in the above loop, wonderful.  Otherwise,
  786.      * it could be a 'language' procedure
  787.      * it is a dynamically loaded function - get its pointer and number
  788.      * of arguments from fmgr_dynamic().
  789.      */
  790.     if (procedureId == builtins[i].proid) return INTERNALlanguageId;
  791.  
  792.     procedureTuple = SearchSysCacheTuple(PROOID, (char *) procedureId,
  793.                      NULL, NULL, NULL);
  794.     if (!HeapTupleIsValid(procedureTuple)) {
  795.     elog(WARN, "fmgr: Cache lookup failed for procedure %d\n",
  796.          procedureId);
  797.     return(NULL);
  798.     }
  799.     language = ((struct proc *) GETSTRUCT(procedureTuple))->prolang;
  800.     return language;
  801. }
  802.  
  803. void fmgr_info(procedureId, function, nargs)
  804.      ObjectId procedureId;
  805.      func_ptr *function;
  806.      int    *nargs;
  807. {
  808.     int low, high, i;
  809.  
  810.     int arg_count;
  811.     func_ptr user_fn, fmgr_dynamic();
  812.  
  813.     /*
  814.      * Binary-search the function array for the appropriate procedure.
  815.      */
  816.  
  817.     low = 0;
  818.     high = n_builtins;
  819.     while (low <= high) {
  820.         i = low + (high - low) / 2;
  821.         if (procedureId == builtins[i].proid)
  822.             break;
  823.         else if (procedureId > builtins[i].proid)
  824.             low = i + 1;
  825.         else
  826.             high = i - 1;
  827.     }
  828.  
  829.     /*
  830.      * If we found the procedure in the above loop, wonderful.  Otherwise,
  831.      * it could be a 'language' procedure
  832.      * it is a dynamically loaded function - get its pointer and number
  833.      * of arguments from fmgr_dynamic().
  834.      */
  835.  
  836.     if (procedureId != builtins[i].proid) {
  837.         HeapTuple   procedureTuple;
  838.         struct proc *procedureStruct;
  839.         ObjectId language;
  840.  
  841.         procedureTuple = SearchSysCacheTuple(PROOID, (char *) procedureId,
  842.                          NULL, NULL, NULL);
  843.         if (!HeapTupleIsValid(procedureTuple)) {
  844.         elog(WARN, "fmgr: Cache lookup failed for procedure %d\n",
  845.              procedureId);
  846.         }
  847.         procedureStruct = (struct proc *) GETSTRUCT(procedureTuple);
  848.         language = procedureStruct->prolang;
  849.         switch (language) {
  850.         case INTERNALlanguageId:
  851.         elog(WARN,
  852.              "internal procedure %d is not in the 'builtins' table",
  853.              procedureId);
  854.         break;
  855.         case ClanguageId:
  856.         user_fn = fmgr_dynamic(procedureId, nargs);
  857.         break;
  858.         case POSTQUELlanguageId:
  859.         user_fn = NULL;
  860.         *nargs = procedureStruct->pronargs;
  861.         break;
  862.         default:
  863.         elog(WARN,
  864.              "procedure %d is of an unknown language %d",
  865.              procedureId, language);
  866.         }
  867.     }
  868.     else
  869.     {
  870.         user_fn = builtins[i].func;
  871.         *nargs = builtins[i].nargs;
  872.     }
  873.     *function = user_fn;
  874. }
  875.  
  876. /*
  877.  *    fmgr        - return the value of a function call
  878.  *
  879.  *    If the function is a system routine, it's compiled in, so call
  880.  *    it directly.
  881.  *
  882.  *      Otherwise pass it to the the appropriate 'language' function caller.
  883.  *
  884.  *    Returns the return value of the invoked function if succesful,
  885.  *    0 if unsuccessful.
  886.  *
  887.  */
  888. char *
  889. fmgr(va_alist)
  890.     va_dcl
  891. {
  892.     va_list        pvar;
  893.     register    i, j;
  894.     ObjectId    procedureId;
  895.     int         pronargs;
  896.     FmgrValues    values;
  897.     func_ptr    user_fn;
  898.     Boolean isNull;
  899.     isNull = false;
  900.  
  901.     va_start(pvar);
  902.     procedureId = va_arg(pvar, ObjectId);
  903.  
  904.     fmgr_info(procedureId, &user_fn, &pronargs);
  905.  
  906.     if (pronargs > MAXFMGRARGS)
  907.     {
  908.         elog(WARN,
  909.             "fmgr: can\'t pass enough args to function: fid=%d",
  910.              procedureId); 
  911.     }
  912.  
  913.     for (j = 0; j < pronargs; ++j)
  914.         values.data[j] = va_arg(pvar, char *);
  915.  
  916.     va_end(pvar);
  917.  
  918.  
  919.     return c_lang_func_call_ptr(user_fn,pronargs,values, &isNull);
  920.  
  921. #ifdef WAY_COOL_ORTHOGONAL_FUNCTIONS
  922.     switch (fmgr_func_lang(procedureId)) {
  923.     case INTERNALlanguageId:
  924.     case ClanguageId:
  925.         return c_lang_func_call_ptr(user_fn,pronargs,values, &isNull);
  926.         break;
  927.     case POSTQUELlanguageId:
  928.         return postquel_lang_func_call(procedureId,pronargs,values);
  929.         break;
  930.     default:
  931.         elog(WARN,
  932.          "No function caller registered for language");
  933.     }
  934. #endif WAY_COOL_ORTHOGONAL_FUNCTIONS
  935. }
  936.  
  937. char *
  938. fmgr_array_args(procedureId, nargs, args, isNull)
  939.     ObjectId procedureId;
  940.     int nargs;
  941.     char * args[];
  942.     Boolean *isNull;
  943. {
  944.     func_ptr user_fn;
  945.     int true_arguments;
  946.     char *returnValue;
  947.  
  948.     fmgr_info(procedureId, &user_fn, &true_arguments);
  949.  
  950.     return c_lang_func_call_ptr_array(user_fn,true_arguments,args, isNull);
  951.  
  952. #ifdef WAY_COOL_ORTHOGONAL_FUNCTIONS
  953.     switch (fmgr_func_lang(procedureId)) {
  954.     case INTERNALlanguageId:
  955.     case ClanguageId:
  956.         return c_lang_func_call_ptr_array(user_fn,true_arguments,args, isNull);
  957.         break;
  958.     case POSTQUELlanguageId:
  959.         return postquel_lang_func_call_array(procedureId,
  960.                          true_arguments,args);
  961.         break;
  962.     default:
  963.         elog(WARN,
  964.          "No function caller for arrays args registered for language");
  965.     }
  966. #endif WAY_COOL_ORTHOGONAL_FUNCTIONS
  967. }
  968.     
  969. /*
  970.  * varargs
  971.  * 
  972.  * func_ptr, n_arguments, args...
  973.  *
  974.  */
  975.  
  976. char *
  977. fmgr_by_ptr(va_alist)
  978.     va_dcl
  979. {
  980.     va_list        pvar;
  981.     FmgrValues    values;
  982.     int            n_arguments, j;
  983.     char        *returnValue = NULL;
  984.     func_ptr    user_fn;
  985.     Boolean isNull;
  986.     isNull = false;
  987.  
  988.     va_start(pvar);
  989.  
  990.     user_fn = va_arg(pvar, func_ptr);
  991.     n_arguments = va_arg(pvar, int);
  992.  
  993.     for (j = 0; j < n_arguments; ++j)
  994.         values.data[j] = va_arg(pvar, char *);
  995.  
  996.     va_end(pvar);
  997.  
  998.     if (n_arguments > MAXFMGRARGS)
  999.      {
  1000.         elog(WARN,
  1001.             "fmgr_by_ptr; can\'t pass enough args to function: nargs=%d",
  1002.              n_arguments); 
  1003.     }
  1004.     return c_lang_func_call_ptr(user_fn,n_arguments,values, &isNull);
  1005. }
  1006.  
  1007. char *
  1008. fmgr_by_ptr_array_args(user_fn, nargs, args, isNull)
  1009.      func_ptr user_fn;
  1010.      int nargs;
  1011.      char * args[];
  1012.      Boolean *isNull;
  1013. {
  1014.     char *returnValue;
  1015.     return c_lang_func_call_ptr_array(user_fn,nargs,args, isNull);
  1016.     }
  1017.